<?php
include_once 'Retriever.php';
include_once '../Model/StepAtRoute.php';
include_once '../Model/Location.php';
include_once '../Utility/simplehtmldom/simple_html_dom.php';
include_once '../Exceptions/MuchParametersException.php';
include_once '../Exceptions/CommunicationException.php';

/**
 * 
 * @author Laura Magrini
 *
 */

class ACRoutePlanner extends Retriever {
	const BY_CAR = 0;
	const BY_PUBLIC_TRANSPORT = 1;
	const BY_PUBLIC_AND_CAR = 2;
	const BY_NO_METRO_NO_TRAIN = 3;
	const BY_PUBLIC_TRANSPORT_AND_BIKE = 4;
	
	const OPT_QUICKEST = 0;
	const OPT_LESS_CHANGES = 1;
	const OPT_LESS_WALK = 2;
	
	private static $NAV = '3';
	private static $ACTION_FOR_PATH_ID = 'dettaglio';
	
	private $atacURL;
	private $params;
	private $city;
	private $serviceName;
	private $separator;
	private $plus;
	private $steps;
	private $descs;
	
	function __construct() {
		$this->plus = '+';
		$this->separator = '&';
		$this->serviceName = 'percorso';
		$this->city = 'Roma';
		$this->atacURL = "http://muovi.roma.it/percorso/?";
		
		$this->params = array('start_address'=>null,
		'start_place'=>$this->city,
		'stop_address'=>null,
		'stop_place'=>$this->city,
		//'service'=>$this->serviceName,
		//'action'=>'submit',
		//'nav'=>2,
		'mezzo'=>1,
		'opzioni'=>0,
		'day'=>10,
		'month'=>05,
		'year'=>10,
		'hour'=>15,
		'minute'=>43,
		'Submit'=>'Calcola'
		);
		
		$this->paramsWithStopID = array(
			'id_linea'=>null,
			'service'=> 'paline',
			'action'=> 'dettaglio_linea',
			'nav'=> 2,
			'Submit' => 'Invia'
		);
				
		$this->steps = null;
	}
	
		
	/**
	 * Rende il percorso dal punto $here al punto $there ottenuto
	 * con le opzioni di default (mezzo pubblico, pi� veloce)
	 * @param unknown_type $here
	 * @param unknown_type $there
	 * @return unknown_type
	 */
	function getPathFromHereToThere($step) {
	   if ($step instanceOf StepRoute)
		{	
			unset($this->steps);
			$this->steps = null;
			$here = $step->getstart();
			$there = $step->getend();
			if (($here instanceOf Location) && ($there instanceOf Location))
			{
			//Riempio il vettore dei parametri
				$this->params['mezzo'] = $step->getmezzo();
				$this->params['day'] = $step->getdd();
				$this->params['month'] = $step->getmo();
				$this->params['year'] = $step->getyy();
				$this->params['hour'] = $step->gethh();
				$this->params['minute'] = $step->getmin();
			
				$this->params['start_address'] = $here->getAddress();
				$this->params['stop_address'] = $there->getAddress();
			
				$this->params['start_address'] = str_replace(" ", "+", $this->params['start_address']);
				$this->params['stop_address'] = str_replace(" ", "+", $this->params['stop_address']);
			
			
			//Costruisco l'url con i parametri giusti
				$url= $this->atacURL;
				$flag=1;
				foreach($this->params as $key => $value)
				if($flag){
					$flag=0;
					$url.=$key."=".$value;
				}
				else
					$url = $url."&".$key."=".$value;

				$pageContent = $this->getHTMLPageFromURL($url); //si trova nella classe Retriever.php				
				if ($pageContent==false)
				{
					return null;
				}	
				$html = str_get_html($pageContent);		//prendo il codice html della pagina
				$text = $html->plaintext; //prendo la pagina in formato testo
				
			//verifico la presenza di errori
				$pos = strpos($text,"servizio");
				$pos2 = strpos($text,"attivo");
				$pos3 = strpos($text,"non");

			//Il problema riguarda l'intero servizio
				if(($pos==true) && ($pos2==true) && ($pos3==true)) {
 					throw new CommunicationException ("ACRoutePlanner: No Response from ATAC", 0);
					return null;
				}
			
			//Il problema riguarda solo quella richiesta
				if ((strpos($text, "tecnici")==true) && ((strpos($text, "problemi")==true))) {
					throw new CommunicationException ("ACRoutePlanner: Service Not Available", 0);
					return null;
				}
				if ((strpos($text, "Correggi")==true) && ((strpos($text, "(molti trovati)")==true))) {									
					throw new MuchParametersException($pageContent);
					return null;
				}	
				
			//echo $text;
			//comincio a cercare i tag giusti per determinare il percorso
			$ret0 = $html->find('div[class=banda0]');

			if ($ret0 == null)
			{
				//Libero memoria e rendo null
				unset($ret0);
				$html->clear();
				unset($html);
				return null;
			}
			//prendo il contenuto della prima descrizione
			$this->addStepToList($this->strToPathObject($ret0[0], $step));
			//$this->addBusToList($this->strToBusObject($ret0[0], $busStop));
			$ret0[0]->clear();
			unset($ret0[0]);
			unset($ret0);			
			
			
			//� necessario prendere i valori nello stesso ordine 
			//in cui vengono restituiti da atac
			$ret1 = $html->find('div[class=banda1]');
			$ret2 = $html->find('div[class=banda2]');
			
			$conta1=count($ret1); //numero di banda1
			$conta2=count($ret2); //numero di banda2
			
			//il numero di banda2 non pu� mai essere > delle banda1
				for($i=0;$i<$conta1;$i++){
					if($ret1[$i]!=null){
						$this->addStepToList($this->strToPathObject($ret1[$i],$step));
						$ret1[$i]->clear();
					}
					if($i<$conta2){
						if($ret2[$i]!=null){
							$this->addStepToList($this->strToPathObject($ret2[$i],$step));
							$ret2[$i]->clear();
						}
					}
				}
				
			unset($ret1);
			unset($ret2);
			$html->clear();
			unset($html);
			return $this->steps;		
		}
		else
			throw new Exception ("ACRoutePlanner.getPathFromHereToThere: Parameters MUST be Location type");
	}else
			throw new Exception ("ACRoutePlanner.getPathFromHereToThere: Parameters MUST be StepRoute type");
		
	}
	
	private function muchaddress($html){
		$ret0 = $html->find('option[value=');
		$conta1=count($ret0);
		echo $conta1;
	}
	
	
	private function strToPathObject($rawStr, $stepRoute) {
		$res = $rawStr->find('a');
		if (isset($res[0])) // tag a presente
		{
			$href = $res[0]; //memorizzo l'href che contiene la mappa
		}
		else { //non � presente il tag 'a' quindi non posso trovare informazioni
			return null;
		}
		$str = $rawStr->plaintext;
		$str=str_replace("&#39;", "'", $str);
		
		$parts = explode("Mappa) ",$str);
		$line = trim($parts[1]);
		$parts = explode("\n",$line);
		$line=trim($parts[0]);
		$palina=null;
		$tempo=null;
		$metri=null;
		$stopID=null;
				
		for($i=1; $i<count($parts);$i++){
			$parts[$i]=trim($parts[$i]);
			if(empty($parts[$i])) continue;
			
			//print("STEP CORRENTE: ".$parts[$i]."\n");
						
			if (stristr($parts[$i], "Fermata)")) //se è presente Palina prendo solo i dati che la precedono e la seguono
			{	
				$i=$i+2;
				
				while(trim($parts[$i])==null || trim($parts[$i])=="" || trim($parts[$i])==" ") $i++;
				$parts[$i]=str_replace("(partenza )","",$parts[$i]);//se trovo una partenza senza orario pulisco la stringa
				$palina.=" ".trim($parts[$i]);
				$i++;
				
				while(trim($parts[$i])==null || trim($parts[$i])=="" || trim($parts[$i])==" ") $i++;
				$parts[$i]=str_replace("(partenza )","",$parts[$i]);
				$palina.=" ".trim($parts[$i]);
				
				$palina = ltrim($palina);
				
				//$i=$i+2;
				//$palina=trim($parts[$i]);
				//$i=$i+6;
				//$palina.=" ".trim($parts[$i]);
				//$app = explode("Fermata)",$parts[$i]);
				//$palina = $app[1];
				//unset($app);
			}
			
			else if (stristr($parts[$i], "Tempo previsto: ")){
				$app = explode("Tempo previsto: ",$parts[$i]);
				$tempo = $app[1];
				unset($app);
			}
			else if (stristr($parts[$i], "Metri percorsi: ")){
				$app = explode("Metri percorsi: ",$parts[$i]);
				$metri = $app[1];
				unset($app);
			}
			else{
				$this->addDescToStep($parts[$i]);	
			}
		}
		
		$step = new StepAtRoute($line, $this->descs, $palina, $tempo, $metri, $stopID);
		
		unset($this->descs);
		$this->descs=null;
		return $step;
	}
	
	private function addDescToStep($desc) {
		if (($desc != null) || ($desc != " ") || ($desc != "\n"))
		{
			if ($this->descs==null)
			{
				$this->descs = array($desc);	
			}
			else
				array_push($this->descs,$desc);
		}
	}
	
	private function addStepToList($step) {
		
		if ($step instanceOf StepAtRoute)
		{
		
			if ($this->steps==null)
			{
				$this->steps = array($step);	
			}
			else
				array_push($this->steps,$step);
		}
		else
			throw new WrongParametersException("Class: ACRoutePlanner. Method: addStepToList($step). 
			Parameter must be StepRoute type");
	}
	
	
	function getPathFromHereToThereWithOptions($step) {
			//funzione per il percorso con opzioni settate
	}
	
	function getPathIDForLineNumber($lineNumber, $direzione) {
		
			$infoManager = new InfoManager();
			
			$pathID = $infoManager->getPathIDForLineAndDirection($lineNumber, $direzione);//array di oggetti busstop
			return $pathID;
			
	}
	
	function getStopIDForLineNumber($pathid, $descrizione) {
		
			$infoManager = new InfoManager();
			$descrizione=explode(": ",$descrizione);
			$stopname=$descrizione[1];	
			$path = $infoManager->getCachedPath($pathid); //array di oggetti busstop
			if(count($path)>0){
				$stops=$path->getStops();
				for ($contatore=0; $contatore < count($stops); $contatore++) {
					if(strcmp($stops[$contatore]->getStopName(), $stopname)==0){
						return $stops[$contatore]->getAtacID();
					}
				}
			}
			return null;
			
	}
	
	
}



?>